//登录变量
var id = +localStorage.getItem('id') ? +localStorage.getItem('id') : 1,
    storage = localStorage,
    nowUser,
    userArr = [];

//音乐flag
document.querySelector('#mStart').play();
var play = false;

// storage.clear();
console.log(storage);


//定义tools 工具包
var tools = {
    __mix__: function () {
        for (var i = 0; i < arguments.length; i++) {
            for (var k in this) {
                arguments[i][k] = this[k];
            }
        }
    },
    extend: function () {
        for (var i = 0; i < arguments.length; i++) {
            for (var k in arguments[i]) {
                this[k] = arguments[i][k];
            }
        }
    },
    in: function () {
        this.style.zIndex = 99999;
        this.style.opacity = 1;
    },
    out: function () {
        var that = this;
        setTimeout(function () {
            that.style.zIndex = -1;
        }, 1000);
        this.style.opacity = 0;
    }
};


//得到用户数据库数组
reUserArr();

function reUserArr() {
    userArr = [];
    for (var k in storage) {
        if (+k) {
            userArr.push(JSON.parse(storage[k]));
        }
    }
}


var logBox = document.querySelector("#loginBox"),
    logBtn = logBox.querySelector("[type=submit]"),
    gameStart = false;

//注册变量
var regBtn = logBox.querySelector("[type=button]"),
    regBox = document.querySelector("#register"),
    regIn = regBox.querySelector("#regIn"),
    regCancel = regBox.querySelector("#regCancel");

//信息变量
var msg = document.querySelector("#msg");
msg.userBar = msg.querySelector("#userName");
msg.titleBar = msg.querySelector("#title");
msg.scoreBar = msg.querySelector("#score");
msg.lengthBar = msg.querySelector("#length");
msg.speedBar = msg.querySelector("#speed");
msg.highBar = msg.querySelector("#high");
msg.titleArr = ["无名小蛇", "眼镜蛇", "莽山烙铁头", "眼镜王蛇", "死神黑曼巴蛇"];

// var msg = {
//     DOM : document.querySelector("#msg"),
//     get : function(id){
//         return this.DOM.querySelector('#' + id);
//     },
//     userBar : msg.get("userName"),
//     titleBar : msg.get("title"),
//     scoreBar : msg.get("score"),
//     lengthBar : msg.get("length"),
//     speedBar : msg.get("speed"),
//     highBar : msg.get("high"),
//     titleArr : ["无名小蛇", "眼镜蛇", "莽山烙铁头", "眼镜王蛇","死神黑曼巴蛇"]
// };
//游戏得分
var game = {};
//利用闭包储存得分和长度      可以和msg对应绑定
game.score = (function () {
    var score = 0;
    return {
        get score() {
            return score;
        },
        set score(v) {
            msg.scoreBar.innerHTML = score = v;
        }
    }
})();
game.length = (function () {
    var length = 0;
    return {
        get length() {
            return length;
        },
        set length(v) {
            msg.lengthBar.innerHTML = length = v;
        }
    };
})();

//定义regBox淡入淡出
// regBox.in = function () {
//     this.style.zIndex = "99999";
//     this.style.opacity = 1;
// };
// regBox.out = function () {
//     this.style.zIndex = "-1";
//     this.style.opacity = 0;
// };
//定义logBox淡入淡出
// logBox.in = regBox.in;
// logBox.out = regBox.out;
tools.__mix__(regBox, logBox);
//定义regBox重置
regBox.reset = function () {
    for (var i = 0; i < regInputs.length; i++) {
        regInputs[i].value = "";
        regInputs[i].className = "";
        regTip[i].style.opacity = "0";
    }
};


//控制regBox淡入淡出
//点击注册
regBtn.onclick = function () {
    regBox.querySelector("#regUser").focus();
    regBox.reset();
    regBox.in();
};
//点击立即注册注册
regIn.onclick = function () {
    //判断是否符合要求
    for (var i = 0; i < regInputs.length; i++) {
        if (!regInputs[i].classList.contains("right")) {
            break;
        }
    }

    if (i === regInputs.length) {
        //得到数据建立新用户
        var regName = regBox.querySelector("#regUser").value,
            regPass = regBox.querySelector("#regPass").value,
            regScreen = regBox.querySelector("#screenName").value,
            newUser = new User(regName, regPass, regScreen);
        //刷新用户数组
        reUserArr();
        logBox.querySelector("[type=text]").focus();
        regBox.out();
    }
};
//点击取消
regCancel.onclick = function () {
    logBox.querySelector("[type=text]").focus();
    regBox.out();
};


//验证注册信息
var regInputs = regBox.querySelectorAll("label>input"),
    regTip = regBox.querySelectorAll("span + span");
//绑定判定事件
for (i = 0; i < regInputs.length - 1; i++) {
    regInputs[i].index = i;
    regInputs[i].onblur = function () {
        if (regTest(this.value)) {
            this.className = "right";
            regTip[this.index].style.opacity = "0";
        } else {
            this.className = "false";
            regTip[this.index].style.opacity = "1";
        }
    };
}
//密码确认
regInputs[regInputs.length - 1].onkeyup = function () {
    if (this.value === regInputs[regInputs.length - 2].value) {
        this.className = "right";
        regTip[regTip.length - 1].style.opacity = "0";
    } else {
        this.className = "false";
        regTip[regTip.length - 1].style.opacity = "1";
    }
};


//注册验证函数
function regTest(string) {
    //正则
    var regexp = /^[\u4e00-\u9fa5\w]{4,}$/;
    //验证
    return regexp.test(string);
}


//注册函数
function User(userName, passWord, screenName) {
    this.userName = userName;
    this.passWord = passWord;
    this.screenName = screenName;
    var json = {};
    for (var k in this) {
        json[k] = this[k];
    }
    json.id = id;
    json = JSON.stringify(json);
    localStorage.setItem(id, json);
    id++;
    localStorage.setItem("id", id);
    console.log("注册成功");
}



//控制logBox淡入淡出
logBtn.onclick = function () {
    var logName = logBox.querySelector("[type=text]").value,
        logPass = logBox.querySelector("[type=password]").value;
    if (test(logName, logPass)) {
        //登录成功
        msg.userBar.innerHTML = nowUser.screenName;
        msg.highBar.innerHTML = nowUser.high.score;
        logBox.out();
        console.log("成功登录");
        gameStart = true;
        //开始游戏
        control.reset();
        document.querySelector('#mStart').pause();
        document.querySelector('#mGamming').play();
        play = true;
    } else {
        console.log("用户名或密码错误");
    }
};


//登录验证
function test(name, key) {
    for (var i = 0; i < userArr.length; i++) {
        if (name === userArr[i].userName && key === userArr[i].passWord) {
            console.log("成功验证");
            nowUser = userArr[i];

            //用户计分设置
            nowUser.high = (function () {
                var score = nowUser.score ? +nowUser.score : 0;
                return {
                    get score() {
                        return score;
                    },
                    set score(v) {
                        msg.highBar.innerHTML = nowUser.score = score = v;
                        //实时上传数据库
                        var json = JSON.stringify(nowUser);
                        localStorage.setItem(nowUser.id, json);
                    }
                }
            })();
            return true;
        }
    }
}


/* ------------   GameBox  --------------------- */
//根据页面高度设置gameBox的高度
var box = document.querySelector('#box'),
    boxH = document.body.offsetHeight * .8,
    ulArr = [],
    ul = box.querySelector('.col'),
    i,
    mask = box.querySelector('#mask'),
    reGameBtn = mask.querySelector('.btn1'),
    rankBtn = mask.querySelector('.btn2');
//设置box的宽高
boxH -= boxH % 15; //让盒子刚好可以容纳
box.style.height = box.style.width = boxH + 'px';
//设置遮盖的宽高
mask.style.height = mask.style.width = boxH + 'px';
//生成栅格系统
ul.style.width = ul.style.height = boxH + 'px';
var ulH = ul.offsetHeight,
    lisH = ul.querySelector('li').offsetHeight;
//2d栅格系统
for (i = 0; i < Math.pow((ulH / lisH), 2); i++) {
    ulArr.push('<li></li>');
}
ul.innerHTML = ulArr.join("");

//定义遮盖的出现和退出
// mask.in = function () {
//     this.style.opacity = 1;
//     this.style.zIndex = 1000;
// };
// mask.out = function () {
//     this.style.opacity = 0;
//     this.style.zIndex = -1;
// };
tools.__mix__(mask);

//点击重新开始
reGameBtn.onclick = function () {
    control.reset();
    mask.out();
    gameStart = true;
};

// 点击排行榜
var rank = box.querySelector('#rank'),
    rankNames = rank.querySelectorAll('.rank_name'),
    rankScores = rank.querySelectorAll('.rank_score'),
    scoreArr = [];
//得到所有的分数数组
for (var i = 0, len = rankScores.length; i < len; i++) {
    scoreArr[i] = parseInt(rankScores[i].innerHTML);
}
//添加方法 控制rank的淡入淡出
tools.__mix__(rank);

//点击查看排行  rank淡入
rankBtn.onclick = function () {
    rank.in();
};
//点击rank  rank淡出
rank.onclick = function () {
    rank.out();
};
//建立rank数据
var rankNumb = (function () {
    var rankData = [{
            name: 'Serioust',
            score: 688
        },
        {
            name: 'Serioust',
            score: 588
        },
        {
            name: 'Serioust',
            score: 488
        },
        {
            name: 'Serioust',
            score: 388
        },
        {
            name: 'Serioust',
            score: 288
        },
        {
            name: 'Serioust',
            score: 188
        },
        {
            name: 'Serioust',
            score: 88
        },
    ];
    return {
        init: function(){
            //向本地缓存取出内容
            var rank = window.localStorage.getItem('rank');
            //如果有  就让闭包数据为取出的内容   如果没有就使用闭包的默认数据
            if(rank){
                rankData = JSON.parse(rank);
            }
            //数据进行渲染
            rankRender(rankData);
        },
        get rankData() {
            return rankData;
        },
        set rankData(user) {
            var scoreArr = [];
            //得到分数数组
            for(var i = 0, len = rankData.length; i < len; i++){
                scoreArr[i] = +rankData[i].score;
            }
            var max = maxScore(scoreArr);
            //对分数数组进行遍历
            for(var i = 0, len = scoreArr.length; i < len; i++){
                //如果比最大分数大
                if(+user.score > scoreArr[max]){
                    //插入第一个
                    rankData.splice(0, 0, { name:user.name, score: +user.score });
                    //删除最后一个
                    rankData.pop();
                    //渲染数据
                    rankRender(rankData);
                    //如果在中间  比当前小  比后一个大
                } else if(+user.score < scoreArr[i] && +user.score > scoreArr[i + 1]) {
                    //插入到对应位置
                    rankData.splice(i+1, 0, { name:user.name, score:+user.score });
                    //删除最后一个
                    rankData.pop();
                    //渲染数据
                    rankRender(rankData);
                }
            }
        }
    };
})();





//设置rank和rankData 数据同步
function rankRender(rankData){
    //渲染到页面中
    for(var i = 0, len = rankData.length; i < len; i++) {
        rankNames[i].innerHTML = rankData[i].name;
        rankScores[i].innerHTML = rankData[i].score;
    }
    //同步到本地数据库中
    window.localStorage.setItem('rank', JSON.stringify(rankData));
}


//得到数组中的最大项
function maxScore(arr) {
    var maxIndex = 0,
        maxValue = arr[0];

    for(var i = 0; i < arr.length; i++){
        if(maxValue < arr[i]) {
            maxIndex = i;
            maxValue = arr[i];
        }
    }
    return maxIndex;
}

//排行榜初始化
rankNumb.init();







/* ------------------------   贪吃蛇的设置    ------------------------------- */
//snake 数据初始化
var snake = document.querySelector("#snake"),
    timer = null, //总控计时器时间
    state = "left", //开始状态
    snakeSpeed = 500, //开始速度
    deg = (function () {
        var deg = 1;
        return {
            get deg() {
                return deg;
            },
            set deg(v) {
                msg.speedBar.innerHTML = deg = v;
                control.speed(deg);
                control.move();
            }
        }
    })();





/* -----------------------------    游戏总控制   ----------------------------------- */

//定义总控
var control = {
    //设置初始化
    reset: function () {
        //信息初始化
        msg.titleBar.innerHTML = msg.titleArr[0];
        deg.deg = 1;
        //得分初始化
        game.score.score = 0;
        game.length.length = 5;


        //蛇身初始化
        var snakeLis = snake.querySelectorAll("li"),
            ulLis = ul.querySelectorAll("li"),
            i;
        for (i = snakeLis.length - 1; i > 4; i--) {
            snakeLis[i].parentNode.removeChild(snakeLis[i]);
        }
        snake.style.left = snake.style.top = lisH * 10 + "px";
        for (i = 0; i < snakeLis.length; i++) {
            snakeLis[i].style.top = 0;
            snakeLis[i].style.left = lisH * i + "px";
            snakeLis[i].className = "";
        }
        snakeLis[0].className = "header";
        state = "left";
        //食物初始化
        for (i = 0; i < ulLis.length; i++) {
            ulLis[i].className = "";
        }
        food.in(6);
        //计时初始化
        clearInterval(food.timer);
        clearInterval(snake.judge);
        clearInterval(timer);

        //开始对时间计时
        food.timer = setInterval(food.eat, 20);
        snake.judge = setInterval(control.eatSelf, 50);

        // clearInterval(gameTimer);
    },
    //自动移动
    move: function () {
        clearInterval(timer);
        timer = setInterval(function () {
            control.go(state);
        }, snakeSpeed);
    },
    //暂停
    stop: function () {
        clearInterval(timer);
    },
    //移动速度
    speed: function (deg) {
        //等级预处理
        if (deg > 5) {
            deg = 5;
        }
        if (deg < 1) {
            deg = 1;
        }
        //速度设置
        switch (deg) {
            case 1:
                snakeSpeed = 500;
                break;
            case 2:
                snakeSpeed = 400;
                break;
            case 3:
                snakeSpeed = 300;
                break;
            case 4:
                snakeSpeed = 200;
                break;
            case 5:
                snakeSpeed = 100;
                break;
            case 6:
                snakeSpeed = 60;
                break;
        }
    },
    //设置移动
    go: function (direction) {
        //每次移动进行节点捕获
        var firstLis = snake.firstElementChild,
            lastLis = snake.lastElementChild;
        //设置头部样式
        lastLis.classList.add("header");
        firstLis.classList.remove("header");
        //设置方向
        switch (direction) {
            case "up":
                state = "up";
                lastLis.style.top = firstLis.offsetTop - 15 + "px";
                if (lastLis.offsetTop < -150) {
                    lastLis.style.top = ul.offsetHeight - 165 + "px";
                }
                lastLis.style.left = firstLis.offsetLeft + "px";
                break;
            case "down":
                state = "down";
                lastLis.style.top = firstLis.offsetTop + 15 + "px";
                if (lastLis.offsetTop >= ul.offsetHeight - 150) {
                    lastLis.style.top = -150 + "px";
                }
                lastLis.style.left = firstLis.offsetLeft + "px";
                break;
            case "left":
                state = "left";
                lastLis.style.top = firstLis.offsetTop + "px";
                lastLis.style.left = firstLis.offsetLeft - 15 + "px";
                if (lastLis.offsetLeft < -150) {
                    lastLis.style.left = ul.offsetWidth - 165 + "px";
                }
                break;
            case "right":
                state = "right";
                lastLis.style.top = firstLis.offsetTop + "px";
                lastLis.style.left = firstLis.offsetLeft + 15 + "px";
                if (lastLis.offsetLeft >= ul.offsetWidth - 150) {
                    lastLis.style.left = -150 + "px";
                }
                break;
        }
        snake.insertBefore(lastLis, firstLis);
    },
    //身体增长
    grow: function () {
        var li = document.createElement("li");
        li.style.top = snake.firstElementChild.nextElementSibling.offsetTop + "px";
        li.style.left = snake.firstElementChild.nextElementSibling.offsetLeft + "px";
        snake.appendChild(li);
    },
    //判断自身吃掉
    eatSelf: function () {
        //每次监听头部和身体的位置 ，如果重合，就判定吃到自己
        var snakeHead = snake.querySelector(".header"),
            headerTop = snakeHead.offsetTop,
            headerLeft = snakeHead.offsetLeft,
            i,
            snakeLis = snake.querySelectorAll("li");
        for (i = 1; i < snakeLis.length; i++) {
            if (snakeLis[i].offsetTop === headerTop && snakeLis[i].offsetLeft === headerLeft) {
                control.stop();
                gameStart = false;
                //吃掉自己
                snakeHead.classList.add("end");
                //对最高分进行判定
                rankNumb.rankData = { name : nowUser.screenName, score : nowUser.high.score };
                mask.in();
            }
        }
    }
};





/* -------------------------------------   食物总控制   ----------------------------------- */
var food = {
    arr: [],
    in: function (n) {
        for (var i = 0; i < n; i++) {
            var foodIndex = 0,
                ulLis = ul.querySelectorAll("li");
            change();
            //利用递归，使生成的食物与蛇体不会重合
            function change() {
                foodIndex = Math.floor(Math.random() * ulLis.length);
                var foodTop = ulLis[foodIndex].offsetTop - 150,
                    foodLeft = ulLis[foodIndex].offsetLeft - 150;
                var snakeLis = snake.querySelectorAll("li"),
                    i;
                for (i = 0; i < snakeLis.length; i++) {
                    if (foodTop === snakeLis[i].offsetTop && foodLeft === snakeLis[i].offsetLeft) {
                        change();
                        return;
                    }
                }
            }

            food.arr.push(foodIndex);
            ulLis[foodIndex].className = "food";
        }
    },
    eat: function () {
        var headTop = snake.firstElementChild.offsetTop,
            headLeft = snake.firstElementChild.offsetLeft,
            i,
            ulLis = ul.querySelectorAll("li");
        for (i = 0; i < food.arr.length; i++) {
            if (ulLis[food.arr[i]].offsetTop - 150 === headTop && ulLis[food.arr[i]].offsetLeft - 150 === headLeft) {
                //食物消除
                ulLis[food.arr[i]].className = "";
                food.arr.splice(i, 1);
                //蛇身增加
                game.length.length++;
                game.score.score += 10 * (deg.deg * .2 + 1);
                control.grow();
                //生成食物
                food.in(1);
                //最高分判断
                if (game.score.score > nowUser.high.score) {
                    nowUser.high.score = game.score.score;
                    //对rand的判断
                }



                //title梯度

                if (game.score.score < 500) {
                    msg.titleBar.innerHTML = msg.titleArr[0];
                } else if (game.score.score < 1000) {
                    msg.titleBar.innerHTML = msg.titleArr[1];
                } else if (game.score.score < 1300) {
                    msg.titleBar.innerHTML = msg.titleArr[2];
                } else if (game.score.score < 1600) {
                    msg.titleBar.innerHTML = msg.titleArr[3];
                } else {
                    msg.titleBar.innerHTML = msg.titleArr[4];
                }


                //速度梯度
                if (game.score.score < 100) {
                    deg.deg = 1;
                } else if (game.score.score < 200) {
                    deg.deg = 2;
                } else if (game.score.score < 350) {
                    deg.deg = 3;
                } else if (game.score.score < 500) {
                    deg.deg = 4;
                } else if (game.score.score < 1000) {
                    deg.deg = 5;
                } else {
                    deg.deg = 6;
                }
            }
        }
    }
};

//监听输入
onkeyup = function (e) {
    if (gameStart) {
        switch (e.keyCode) {
            case 80: //p    暂停
                control.stop();
                break;
            case 37: //左
                if (state === "right") {
                    break;
                } else {
                    control.go("left");
                    control.move();
                    break;
                }
            case 38: //上
                if (state === "down") {
                    break;
                } else {
                    control.go("up");
                    control.move();
                    break;
                }
            case 39: //右
                if (state === "left") {
                    break;
                } else {
                    control.go("right");
                    control.move();
                    break;
                }
            case 40: //下
                if (state === "up") {
                    break;
                } else {
                    control.go("down");
                    control.move();
                    break;
                }
            case 77: //m
                //音乐的开始与暂停
                if(play){
                    document.querySelector("#mGamming").pause();
                }else {
                    document.querySelector("#mGamming").play();
                }
                play = !play;
        }
    }
};